#!/usr/bin/python2.4
#
#
# jhebert@cs.washington.edu

import sys
import logger
import Queue
from chartRunner6 import ChartRunner


class ChartManager:
  """ This class is the first version of a chart run-time manager.
  It loads charts ot help in this purpose, runs charts, and should
  be allowed to run charts for external ChartManagers. 

  Currently we divide into three ChartRunners for user charts,
  charts from other chartManagers, and charts to help
  the task of chartManaging. """

  def __init__(self):
    self.statusPort=12345
    self.statusLog=logger.Logger()
    self.commandLog=logger.Logger()
    name='UtilityChartRunner'
    logs=(self.statusLog, self.commandLog)
    self.utilityCharts = ChartRunner(name, logs)
    name='ExternalChartRunner'
    self.externalCharts = ChartRunner(name, logs)
    name='InternalChartRunner'
    self.userCharts = ChartRunner(name, logs)

  def CommandLoop(self):
    """ A main command loop, execute simple user commands. """
    while 1:
      try:
        userCommand = raw_input("ChartManager> ")
        commandToken=userCommand.split(' ')[0]
        if(commandToken in ['load']):
          chartName=userCommand.split(' ')[1]
          self.LoadChart(chartName, self.userCharts)
        elif(commandToken in ['run', 'start', 'go']):
          self.RunCharts(self.userCharts)
        elif(commandToken in ['stop']):
          self.StopAllCharts()
        elif(commandToken in ['quit', 'exit', 'q']):
          self.StopAllCharts()
          break
        elif(commandToken in ['log', 'show log', 'display']):
          self.PrintLog()
        else:
          if(len(commandToken)>0):
            print 'Command not found:', commandToken
      except IndexError, err:
        print 'Error on input ->', err
        sys.exit(1)
      except EOFError, err:
        self.StopAllCharts()
        break
      except KeyboardInterrupt, err:
        self.StopAllCharts()
        break

  def PrintLog(self):
    """ Nearly deprecated, print the log. This will be handled
    by the LogHandler chart. """
    try:
      while 1:
        item=self.statusLog.get(False)
        print item
    except Queue.Empty, err:
      pass

  def StopAllCharts(self):
    """ A clean stop. Exit all the charts that we are running. """
    print "Stopping all Chart Runners . . ."
    self.utilityCharts.Stop()
    self.externalCharts.Stop()
    self.userCharts.Stop()

  def LoadChart(self, chartName, chartRunner, args=[]):
    """ Load a chart, to a specific chartRunner. Allow args. """
    error,msg=False,''
    try:
      success,msg=chartRunner.LoadChart(chartName, args)
      error=not success
    except IOError, err:
      print 'Failed to load the chart ->', err
      error,msg=True,err
    except SyntaxError, err:
      print 'Syntax error in chart file ->', err
      error,msg=True,err
    if(not error):
      print 'Sucessfully loaded', chartName
    else:
      print 'Failed to load:', chartName
      print 'Error status:', msg

  def RunCharts(self, chartRunner):
    """ Run the charts for a chartRunner. """
    chartRunner.Run()

  def Run(self):
    """ Start this chartManager. Take user input, start the
    utility charts and print a pretty banner. """
    self.PrintBanner()
    self.SetupUtilityCharts()
    self.CommandLoop()

  def SetupUtilityCharts(self):
    """ Setup the charts: Status Server, Log Handlder and
    Network Manager. """
    self.__LoadLogHandler()
    self.__LoadGridDiscovery()

  def __LoadLogHandler(self):
    """ Manage logs to display output and errors as desired.
    Also handles chart requests for loading nodes and such.
    This also loads a status HTTP server. """
    args=[('logs',(self.statusLog,self.commandLog)),
          ('port',self.statusPort)]
    fileName = './util/LogHandler.chart'
    self.LoadChart(fileName, self.utilityCharts, args)
    self.RunCharts(self.utilityCharts)

  def __LoadGridDiscovery(self):
    """ Load the chart to handle gridDiscovery. """
    args=[('ports', (22222,33333))]
    fileName = './util/GridDiscovery.chart'
    self.LoadChart(fileName, self.utilityCharts, args)
    self.RunCharts(self.utilityCharts)

  def PrintBanner(self):
    """ This should be pretty. """
    print '     /=============\\'
    print '       ChartRunner '
    print '     \=============/'

def main():
  central = ChartManager()
  central.Run()


main()
